/*
 * Hoja de Trabajo no. 1
 * Fecha: 05/julio/2012
 * 
 * Autores:
 *      Maria Alejandra Josue       11496
 *      Mario Galvez                10113
 *      Jorge Luis Martínez         11237
 * 
 * Contiene una clase que maneja las operaciones de un radio definidas
 * en la interface iRadio.
 */
package hojatrabajo1;

/**
 * Implementación de un radio siguiendo los lineamientos de la interface iRadio.
 * 
 * @author Alejandra
 * @author Mario
 * @author Jorge
 */
public class RadioX implements iRadio{
    
    private enum Bandas{
        AM,
        FM
    }
    
    // Definición del rango para AM (los límites son inclusivos)
    private final double cambioAM = 10.0;
    private final double minAM = 530.0;
    private final double maxAM = 1610.0;
    
    // Definición dle rango para FM (los límites son inclusivos)
    private final double cambioFM = 0.2;
    private final double minFM = 87.9;
    private final double maxFM = 108.0; 
    /* NOTA: El último valor es 107.9 pero se aproximó a 108.0 por la aproximación de punto flotante. */
    
    private Bandas bandaActual;
    private double[][] estacionesGuardadas;
    private boolean encendido;
    private double frecuenciaActual;
    // METODOS
    /* 
     * Constructor del radio.
     */
    public RadioX(){
        bandaActual = Bandas.AM;
        
        // Inicializar la memoria guardada
        estacionesGuardadas = new double[2][12];
        for( int memActual = 0; memActual != 12; ++memActual )
            estacionesGuardadas[Bandas.AM.ordinal()][memActual] = minAM;
        for( int memActual = 0; memActual != 12; ++memActual )
            estacionesGuardadas[Bandas.FM.ordinal()][memActual] = minFM;
        
        encendido = false;
        frecuenciaActual = minAM;
    }
    
    /* 
     * Enciende o apaga el Radio.
     * @return True si el radio se enciendió, o false si el
     * radio se apagó.
     */
    @Override
    public boolean Power(){
        encendido = !encendido;
        return encendido;
    }
    
    /* 
     * Cambia la banda de AM a FM o viceversa.
     * @return True si la banda es AM y false si la banda
     * es FM.
     */
    @Override
    public boolean ChangeSignal(){
        if( bandaActual == Bandas.AM ){
            bandaActual = Bandas.FM;
            frecuenciaActual = minFM;
            return false;
        } else {
            bandaActual = Bandas.AM;
            frecuenciaActual = minAM;
            return true;
        }
    }
    
    /* 
     * Adelanta la frecuencia a la siguiente posible.
     * @return La frecuencia actual.
     */
    @Override
    public float NextFreq(){
        if( bandaActual == Bandas.AM ){
            frecuenciaActual += cambioAM;
            if( frecuenciaActual > maxAM )
                frecuenciaActual = minAM;
        } else if( bandaActual == Bandas.FM ) {
            frecuenciaActual += cambioFM;
            if( frecuenciaActual > maxFM )
                frecuenciaActual = minFM;
        }
        
        return (float)frecuenciaActual;
    }
    
    /*
     * Graba la frecuencia actual en el botón dado. Existen únicamente
     * 12 posiciones de memoria (botones) por cada Banda.
     * @return True si la operación fue exitosa, false en caso contrario.
     */
    @Override
    public boolean SaveFreq( int Boton ){
        // Validar el rango del boton
        if( Boton < 1 || Boton > 12 )
            return false;
        
        // Asignar la frecuencia actual a la posicion de memorio
        int posicionMemoria = Boton-1;
        estacionesGuardadas[bandaActual.ordinal()][posicionMemoria] =
                GetFreq();
        return true;
    }
    
    /*
     * Cambia la estación a la grabada en el botón dado. Devuelve la estación
     * actual que se escucha. Existen únicamente 12 posiciones de memoria.
     * @return La frecuencia (nueva) a la que está sintonizada la radio.
     */
    @Override
    public float ChangeTune( int Boton ){
        // Validar el rango del boton
        if( Boton < 1 || Boton > 12 )
            return (float)frecuenciaActual;
        
        // Obtener el valor de la estación
        int posicionMemoria = Boton-1;
        frecuenciaActual = estacionesGuardadas[bandaActual.ordinal()][posicionMemoria];
        
        return (float)frecuenciaActual;
    }
    
    /*
     * @return True si la radio está encendida, false en caso contrario.
     */ 
    @Override
    public boolean IsOn(){
        return encendido;
    }
    
    /*
     * @return True si la banda es AM, y false si es FM.
     */
    @Override
    public boolean IsAm(){
        if( bandaActual == Bandas.AM )
            return true;
        else
            return false;
    }
    
    /*
     * @return La frecuencia actual a la que está sintonizada la radio.
     */
    @Override
    public float GetFreq(){
        return (float)frecuenciaActual;
    }
}
